package exp;

import utils.BasicJPanel;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Path;

public class SobelJPanel extends BasicJPanel implements ChangeListener
{
    private final JLabel imageJLabel;
    private final JLabel filterJLabel;

    public SobelJPanel()
    {
        super();
        setLayout(new BorderLayout());
        {
            JPanel jPanel=new JPanel();
            add(jPanel);
            jPanel.setLayout(new GridLayout(1,2));
            jPanel.add(imageJLabel=new JLabel());
            jPanel.add(filterJLabel=new JLabel());
        }
    }

    private void update()
    {
        final BufferedImage src=(BufferedImage)((ImageIcon)imageJLabel.getIcon()).getImage();
        final BufferedImage filter=new BufferedImage(src.getWidth(),src.getHeight(),BufferedImage.TYPE_INT_RGB);
        //滤波部分
        {
            int[][] f1={{-1,0,1},{-2,0,2},{-1,0,1}};
            int[][] f2={{-1,-2,-1},{0,0,0},{1,2,1}};
            for(int i=1;i<src.getHeight()-1;++i)
                for(int j=1;j<src.getWidth()-1;++j)
                {
                    int sum1=0, sum2=0;
                    for(int k=0;k<3;++k)
                        for(int l=0;l<3;++l)
                        {
                            final int t=GrayJPanel.RGBToGray(src.getRGB(j-1+l,i-1+k));
                            sum1+=t*f1[l][k];
                            sum2+=t*f2[l][k];
                        }
                    filter.setRGB(j,i,GrayJPanel.grayToRGB((int)Math.sqrt(sum1*sum1+sum2*sum2)));
                }
        }
        filterJLabel.setIcon(new ImageIcon(filter));
    }

    public void update(Path path) throws IOException, BmpStructureErrorException
    {
        final Bmp bmp=new Bmp(path);
        imageJLabel.setIcon(new ImageIcon(bmp.getImage()));
        update();
    }

    public String getButtonName()
    {
        return "<html>第7章选做1：SOBEL";
    }

    public void stateChanged(ChangeEvent e)
    {
        update();
    }
}
